<template>
  <div>

  </div>
</template>
<script setup lang="ts">
//type 和 interface 的区别
// 基础数据类型
// type和interface都可以定义 对象 和 函数

// type可以定义其他数据类型，如字符串、数字、元祖、联合类型等，而interface不行




// 扩展
// interface 可以扩展 type，type 也可以扩展为 interface，但两者实现扩展的方式不同。

// interface 是通过 extends 来实现

// type 是通过 & 来实现

// interface A {
//   a: string
// }
// interface B extends A {
//   b: number
// }
// const obj: B = { a: `小杜杜`, b: 7 }
// console.log(obj);

// type c = {
//   a: string
// }
// type D = c & {
//   b: number
// }
// const obj1:D = { a: `小杜杜`, b: 7 }

// console.log(obj1);

// type E = { a: string }
// interface F  extends E{
//   b: number
// }
// const obj2:F = { a: `小杜杜`, b: 7 }
// console.log(obj2);


// interface E  { a: string }
// type F = {
//   b: number
// } & E
// const obj2:F = { a: `小杜杜`, b: 7 }
// console.log(obj2);


// 重复定义
// interface 可以多次被定义，并且会进行合并，但type不行
// 接口支持声明合并，类型别名不支持：
// 接口的声明可以合并，即多个接口可以共享同一个名称，并合并它们的成员。
// 类型别名则不支持这种声明合并。



// interface A {
//   a: string
// }
// interface A {
//   b: number
// }
// const obj:A = { a: `小杜杜`, b: 7 }
// console.log(obj);



// 反例
// type A = {
//   a: string
// }
// type A = {
//   b: number
// }

// const obj:A = { a: `小杜杜`, b: 7 }
// console.log(obj);



// 类型别名无法被extends和implements：
// 当需要扩展类型时，应使用接口。
// 类型别名更适合用于定义联合类型、交叉类型或非对象类型。





// 在属性中引用类型别名自身：
// 类型别名可以在对象属性中引用自己，形成递归类型。
// 但不能直接使用类型别名来引用自身，否则会导致循环引用。

// interface RootObject {
//   value: number;
//   left: Left;
//   right: null;
// }

// interface Left {
//   value: number;
//   left: null;
//   right: Right;
// }

// interface Right {
//   value: number;
//   left: null;
//   right: null;
// }



// type TreeNode<T>= {
//   value: T;
//   left: TreeNode<T>|null;
//   right: TreeNode<T>|null;
// }


// interface TreeNode<T>  {
//   value: T;
//   left: TreeNode<T>|null;
//   right: TreeNode<T>|null;
// }


// let tree:TreeNode<number> = {
//   value: 1,
//   left: {
//     value: 2,
//     left: null,
//     right: {
//       value: 3,
//       left: null,
//       right: null
//     }
//   },
//   right: null
// };

// console.log(tree);



//关键字  in 

// type A = 'name'|'age'|'height'
// type B = {
//   [P in A]: string|number
// }
// let a:B = {
//   name: 'a',
//   age: '18',
//   height:188
// }
// console.log(a);


// interface InfoA {
//   name: string;
//   age: number;
// }
// interface InfoB {
//   name: string;
//   flage: boolean;
// }

// const setInfo = (data: InfoA | InfoB) => {
//   if('age' in data){
//     console.log(data.age);
//   }
//   if('flage' in data){
//     console.log(data.flage);
//   }
// };

// setInfo({name: '小杜杜', age: 7}) // "我的名字是：小杜杜，年龄是：7" 
// setInfo({name: '小杜杜', flage: true}) // "我的名字是：小杜杜，性别是：true"



// keyof

// interface Props {
//   name: string;
//   age: number;
//   sex: boolean
// }
// type TKeys = keyof Props;
// let a:TKeys = 'name'
// let b:TKeys = 'age'
// let c:TKeys = 'sex'
// let d:TKeys = 'test'
// console.log(a,b,c,d);

//Partial
// interface Props {
//   name: string;
//   age: number;
// }
// const info: Props = {
//   name: '小王',
//   age: 7
// }
// const info1: Partial<Props> = {
//   name: '小王',
// }
// console.log(info, info1);


// Record
//用于创建对象类型，其中键和值的类型可以分别指定。
// interface Props {
//   name: string;
//   age: number;
// }
// type InfoProps = 'JS'|'TS'

// const Info: Record<InfoProps, Props> = {
//         JS: {
//             name: '小徐',
//             age: 7
//         },
//         TS: {
//             name: 'TypeScript',
//             age: 11
//         }
// }
// console.log(Info);

// type ReadOnly<T> = {
//   readonly [P in keyof T]: T[P];
// }
// interface Person {
//   name: string;
//   age: number;
// }
// let readOnlyPerson:ReadOnly<Person> = {
//   name: "Alice",
//   age: 25
// };
// console.log(readOnlyPerson);



// extends
// extends：检验是否拥有其属性
//使用类型别名定义条件类型
// type Message<T> = T extends string ? string : never;

// let msg1: Message<string> = "Hello";  // 正确
// let msg2: Message<number> = 42;    // 错误
// console.log(msg1,msg2);



//Pick
interface Props {
        name: string,
        age: number,
        sex: boolean
}
type nameProps = Pick<Props, 'name' | 'age'>
const info: nameProps = {
        name: '小徐',
        age: 7
}
console.log(info);

</script>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}

.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}

.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
